home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / gui / x / twm93053.lha / twm / twm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-31  |  24.1 KB  |  866 lines

  1. /*****************************************************************************/
  2. /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  3. /**                          Salt Lake City, Utah                           **/
  4. /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
  5. /**                        Cambridge, Massachusetts                         **/
  6. /**                                                                         **/
  7. /**                           All Rights Reserved                           **/
  8. /**                                                                         **/
  9. /**    Permission to use, copy, modify, and distribute this software and    **/
  10. /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  11. /**    granted, provided that the above copyright notice appear  in  all    **/
  12. /**    copies and that both  that  copyright  notice  and  this  permis-    **/
  13. /**    sion  notice appear in supporting  documentation,  and  that  the    **/
  14. /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
  15. /**    in publicity pertaining to distribution of the  software  without    **/
  16. /**    specific, written prior permission.                                  **/
  17. /**                                                                         **/
  18. /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
  19. /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
  20. /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
  21. /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
  22. /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
  23. /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
  24. /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
  25. /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
  26. /*****************************************************************************/
  27.  
  28.  
  29. /***********************************************************************
  30.  *
  31.  * $XConsortium: twm.c,v 1.124 91/05/08 11:01:54 dave Exp $
  32.  *
  33.  * twm - "Tom's Window Manager"
  34.  *
  35.  * 27-Oct-87 Thomas E. LaStrange    File created
  36.  * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
  37.  ***********************************************************************/
  38.  
  39. #include <stdio.h>
  40. #include <signal.h>
  41. #include <fcntl.h>
  42. #include "twm.h"
  43. #include "add_window.h"
  44. #include "gc.h"
  45. #include "parse.h"
  46. #include "version.h"
  47. #include "menus.h"
  48. #include "events.h"
  49. #include "util.h"
  50. #include "gram.h"
  51. #include "screen.h"
  52. #include "iconmgr.h"
  53. #include <X11/Xproto.h>
  54. #include <X11/Xatom.h>
  55.  
  56. Display *dpy;            /* which display are we talking to */
  57. Window ResizeWindow;        /* the window we are resizing */
  58.  
  59. int MultiScreen = TRUE;        /* try for more than one screen? */
  60. int NumScreens;            /* number of screens in ScreenList */
  61. int HasShape;            /* server supports shape extension? */
  62. int ShapeEventBase, ShapeErrorBase;
  63. ScreenInfo **ScreenList;    /* structures for each screen */
  64. ScreenInfo *Scr = NULL;        /* the cur and prev screens */
  65. int PreviousScreen;        /* last screen that we were on */
  66. int FirstScreen;        /* TRUE ==> first screen of display */
  67. Bool PrintErrorMessages = False;    /* controls error messages */
  68. static int RedirectError;    /* TRUE ==> another window manager running */
  69. static int CatchRedirectError();    /* for settting RedirectError */
  70. static int TwmErrorHandler();    /* for everything else */
  71. char Info[INFO_LINES][INFO_SIZE];        /* info strings to print */
  72. int InfoLines;
  73. char *InitFile = NULL;
  74.  
  75. Cursor UpperLeftCursor;        /* upper Left corner cursor */
  76. Cursor RightButt;
  77. Cursor MiddleButt;
  78. Cursor LeftButt;
  79.  
  80. XContext TwmContext;        /* context for twm windows */
  81. XContext MenuContext;        /* context for all menu windows */
  82. XContext IconManagerContext;    /* context for all window list windows */
  83. XContext ScreenContext;        /* context to get screen data */
  84. XContext ColormapContext;    /* context for colormap operations */
  85.  
  86. XClassHint NoClass;        /* for applications with no class */
  87.  
  88. XGCValues Gcv;
  89.  
  90. char *Home;            /* the HOME environment variable */
  91. int HomeLen;            /* length of Home */
  92. int ParseError;            /* error parsing the .twmrc file */
  93.  
  94. int HandlingEvents = FALSE;    /* are we handling events yet? */
  95.  
  96. Window JunkRoot;        /* junk window */
  97. Window JunkChild;        /* junk window */
  98. int JunkX;            /* junk variable */
  99. int JunkY;            /* junk variable */
  100. unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask;
  101.  
  102. char *ProgramName;
  103. int Argc;
  104. char **Argv;
  105. char **Environ;
  106.  
  107. Bool RestartPreviousState = False;    /* try to restart in previous state */
  108.  
  109. unsigned long black = 1, white = 0;
  110.  
  111. extern void assign_var_savecolor();
  112.  
  113. /***********************************************************************
  114.  *
  115.  *  Procedure:
  116.  *    main - start of twm
  117.  *
  118.  ***********************************************************************
  119.  */
  120.  
  121. main(argc, argv, environ)
  122.     int argc;
  123.     char **argv;
  124.     char **environ;
  125. {
  126.     Window root, parent, *children;
  127.     unsigned int nchildren;
  128.     int i, j;
  129.     char *display_name = NULL;
  130.     unsigned long valuemask;    /* mask for create windows */
  131.     XSetWindowAttributes attributes;    /* attributes for create windows */
  132.     int numManaged, firstscrn, lastscrn, scrnum;
  133.     extern ColormapWindow *CreateColormapWindow();
  134.  
  135.     ProgramName = argv[0];
  136.     Argc = argc;
  137.     Argv = argv;
  138.     Environ = environ;
  139.  
  140.     for (i = 1; i < argc; i++) {
  141.     if (argv[i][0] == '-') {
  142.         switch (argv[i][1]) {
  143.           case 'd':                /* -display dpy */
  144.         if (++i >= argc) goto usage;
  145.         display_name = argv[i];
  146.         continue;
  147.           case 's':                /* -single */
  148.         MultiScreen = FALSE;
  149.         continue;
  150.           case 'f':                /* -file twmrcfilename */
  151.         if (++i >= argc) goto usage;
  152.         InitFile = argv[i];
  153.         continue;
  154.           case 'v':                /* -verbose */
  155.         PrintErrorMessages = True;
  156.         continue;
  157.           case 'q':                /* -quiet */
  158.         PrintErrorMessages = False;
  159.         continue;
  160.         }
  161.     }
  162.       usage:
  163.     fprintf (stderr,
  164.          "usage:  %s [-display dpy] [-f file] [-s] [-q] [-v]\n",
  165.          ProgramName);
  166.     exit (1);
  167.     }
  168.  
  169. #define newhandler(sig) \
  170.     if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)
  171.  
  172.     newhandler (SIGINT);
  173.     newhandler (SIGHUP);
  174.     newhandler (SIGQUIT);
  175.     newhandler (SIGTERM);
  176.  
  177. #undef newhandler
  178.  
  179.     Home = getenv("HOME");
  180.     if (Home == NULL)
  181.     Home = "./";
  182.  
  183.     HomeLen = strlen(Home);
  184.  
  185.     NoClass.res_name = NoName;
  186.     NoClass.res_class = NoName;
  187.  
  188.     if (!(dpy = XOpenDisplay(display_name))) {
  189.     fprintf (stderr, "%s:  unable to open display \"%s\"\n",
  190.          ProgramName, XDisplayName(display_name));
  191.     exit (1);
  192.     }
  193.  
  194.     if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) {
  195.     fprintf (stderr, 
  196.          "%s:  unable to mark display connection as close-on-exec\n",
  197.          ProgramName);
  198.     exit (1);
  199.     }
  200.  
  201.     HasShape = XShapeQueryExtension (dpy, &ShapeEventBase, &ShapeErrorBase);
  202.     TwmContext = XUniqueContext();
  203.     MenuContext = XUniqueContext();
  204.     IconManagerContext = XUniqueContext();
  205.     ScreenContext = XUniqueContext();
  206.     ColormapContext = XUniqueContext();
  207.  
  208.     InternUsefulAtoms ();
  209.  
  210.  
  211.     /* Set up the per-screen global information. */
  212.  
  213.     NumScreens = ScreenCount(dpy);
  214.  
  215.     if (MultiScreen)
  216.     {
  217.     firstscrn = 0;
  218.     lastscrn = NumScreens - 1;
  219.     }
  220.     else
  221.     {
  222.     firstscrn = lastscrn = DefaultScreen(dpy);
  223.     }
  224.  
  225.     InfoLines = 0;
  226.  
  227.     /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */
  228.     ScreenList = (ScreenInfo **) calloc (NumScreens, sizeof (ScreenInfo *));
  229.     if (ScreenList == NULL)
  230.     {
  231.     fprintf (stderr, "%s: Unable to allocate memory for screen list, exiting.\n",
  232.          ProgramName);
  233.     exit (1);
  234.     }
  235.     numManaged = 0;
  236.     PreviousScreen = DefaultScreen(dpy);
  237.     FirstScreen = TRUE;
  238.     for (scrnum = firstscrn ; scrnum <= lastscrn; scrnum++)
  239.     {
  240.         /* Make sure property priority colors is empty */
  241.         XChangeProperty (dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS,
  242.              XA_CARDINAL, 32, PropModeReplace, NULL, 0);
  243.     RedirectError = FALSE;
  244.     XSetErrorHandler(CatchRedirectError);
  245.     XSelectInput(dpy, RootWindow (dpy, scrnum),
  246.         ColormapChangeMask | EnterWindowMask | PropertyChangeMask | 
  247.         SubstructureRedirectMask | KeyPressMask |
  248.         ButtonPressMask | ButtonReleaseMask);
  249.     XSync(dpy, 0);
  250.     XSetErrorHandler(TwmErrorHandler);
  251.  
  252.     if (RedirectError)
  253.     {
  254.         fprintf (stderr, "%s:  another window manager is already running",
  255.              ProgramName);
  256.         if (MultiScreen && NumScreens > 0)
  257.         fprintf(stderr, " on screen %d?\n", scrnum);
  258.         else
  259.         fprintf(stderr, "?\n");
  260.         continue;
  261.     }
  262.  
  263.     numManaged ++;
  264.  
  265.     /* Note:  ScreenInfo struct is calloc'ed to initialize to zero. */
  266.     Scr = ScreenList[scrnum] = 
  267.         (ScreenInfo *) calloc(1, sizeof(ScreenInfo));
  268.       if (Scr == NULL)
  269.       {
  270.           fprintf (stderr, "%s: unable to allocate memory for ScreenInfo structure for screen %d.\n",
  271.                ProgramName, scrnum);
  272.           continue;
  273.       }
  274.  
  275.     /* initialize list pointers, remember to put an initialization
  276.      * in InitVariables also
  277.      */
  278.     Scr->BorderColorL = NULL;
  279.     Scr->IconBorderColorL = NULL;
  280.     Scr->BorderTileForegroundL = NULL;
  281.     Scr->BorderTileBackgroundL = NULL;
  282.     Scr->TitleForegroundL = NULL;
  283.     Scr->TitleBackgroundL = NULL;
  284.     Scr->IconForegroundL = NULL;
  285.     Scr->IconBackgroundL = NULL;
  286.     Scr->NoTitle = NULL;
  287.     Scr->MakeTitle = NULL;
  288.     Scr->AutoRaise = NULL;
  289.     Scr->IconNames = NULL;
  290.     Scr->NoHighlight = NULL;
  291.     Scr->NoStackModeL = NULL;
  292.     Scr->NoTitleHighlight = NULL;
  293.     Scr->DontIconify = NULL;
  294.     Scr->IconMgrNoShow = NULL;
  295.     Scr->IconMgrShow = NULL;
  296.     Scr->IconifyByUn = NULL;
  297.     Scr->IconManagerFL = NULL;
  298.     Scr->IconManagerBL = NULL;
  299.     Scr->IconMgrs = NULL;
  300.     Scr->StartIconified = NULL;
  301.     Scr->SqueezeTitleL = NULL;
  302.     Scr->DontSqueezeTitleL = NULL;
  303.     Scr->WindowRingL = NULL;
  304.     Scr->WarpCursorL = NULL;
  305.     /* remember to put an initialization in InitVariables also
  306.      */
  307.  
  308.     Scr->screen = scrnum;
  309.     Scr->d_depth = DefaultDepth(dpy, scrnum);
  310.     Scr->d_visual = DefaultVisual(dpy, scrnum);
  311.     Scr->Root = RootWindow(dpy, scrnum);
  312.     XSaveContext (dpy, Scr->Root, ScreenContext, (caddr_t) Scr);
  313.  
  314.     Scr->TwmRoot.cmaps.number_cwins = 1;
  315.     Scr->TwmRoot.cmaps.cwins =
  316.         (ColormapWindow **) malloc(sizeof(ColormapWindow *));
  317.     Scr->TwmRoot.cmaps.cwins[0] =
  318.         CreateColormapWindow(Scr->Root, True, False);
  319.     Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured;
  320.  
  321.     Scr->cmapInfo.cmaps = NULL;
  322.     Scr->cmapInfo.maxCmaps =
  323.         MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen));
  324.     Scr->cmapInfo.root_pushes = 0;
  325.     InstallWindowColormaps(0, &Scr->TwmRoot);
  326.  
  327.     Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail = 
  328.       Scr->StdCmapInfo.mru = NULL;
  329.     Scr->StdCmapInfo.mruindex = 0;
  330.     LocateStandardColormaps();
  331.  
  332.     Scr->TBInfo.nleft = Scr->TBInfo.nright = 0;
  333.     Scr->TBInfo.head = NULL;
  334.     Scr->TBInfo.border = 1;
  335.     Scr->TBInfo.width = 0;
  336.     Scr->TBInfo.leftx = 0;
  337.     Scr->TBInfo.titlex = 0;
  338.  
  339.     Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum);
  340.     Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum);
  341.     Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth;
  342.     Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight;
  343.  
  344.     Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1;
  345.  
  346.     if (DisplayCells(dpy, scrnum) < 3)
  347.         Scr->Monochrome = MONOCHROME;
  348.     else
  349.         Scr->Monochrome = COLOR;
  350.  
  351.     /* setup default colors */
  352.     Scr->FirstTime = TRUE;
  353.     GetColor(Scr->Monochrome, &black, "black");
  354.     Scr->Black = black;
  355.     GetColor(Scr->Monochrome, &white, "white");
  356.     Scr->White = white;
  357. #ifdef DEBUG
  358.     printf("black=%lu, white=%lu\n", black, white);
  359. #endif
  360.  
  361.     if (FirstScreen)
  362.     {
  363.         SetFocus ((TwmWindow *)NULL, CurrentTime);
  364.  
  365.         /* define cursors */
  366.  
  367.         NewFontCursor(&UpperLeftCursor, "top_left_corner");
  368.         NewFontCursor(&RightButt, "rightbutton");
  369.         NewFontCursor(&LeftButt, "leftbutton");
  370.         NewFontCursor(&MiddleButt, "middlebutton");
  371.     }
  372.  
  373.     Scr->iconmgr.x = 0;
  374.     Scr->iconmgr.y = 0;
  375.     Scr->iconmgr.width = 150;
  376.     Scr->iconmgr.height = 5;
  377.     Scr->iconmgr.next = NULL;
  378.     Scr->iconmgr.prev = NULL;
  379.     Scr->iconmgr.lasti = &(Scr->iconmgr);
  380.     Scr->iconmgr.first = NULL;
  381.     Scr->iconmgr.last = NULL;
  382.     Scr->iconmgr.active = NULL;
  383.     Scr->iconmgr.scr = Scr;
  384.     Scr->iconmgr.columns = 1;
  385.     Scr->iconmgr.count = 0;
  386.     Scr->iconmgr.name = "TWM";
  387.     Scr->iconmgr.icon_name = "Icons";
  388.  
  389.     Scr->IconDirectory = NULL;
  390.  
  391.     Scr->siconifyPm = None;
  392.     Scr->pullPm = None;
  393.     Scr->hilitePm = None;
  394.     Scr->tbpm.xlogo = None;
  395.     Scr->tbpm.resize = None;
  396.     Scr->tbpm.question = None;
  397.     Scr->tbpm.menu = None;
  398.     Scr->tbpm.delete = None;
  399.  
  400.     InitVariables();
  401.     InitMenus();
  402.  
  403. #ifdef DEBUG
  404.     printf("after InitVars & -Menus\n");
  405. #endif
  406.     /* Parse it once for each screen. */
  407.     ParseTwmrc(InitFile);
  408. #ifdef DEBUG
  409.     printf("after ParseTwmrc\n");
  410. #endif
  411.     assign_var_savecolor(); /* storeing pixels for twmrc "entities" */
  412. #ifdef DEBUG
  413.     printf("after assign_var_savecolor\n");
  414. #endif
  415.     if (Scr->SqueezeTitle == -1) Scr->SqueezeTitle = FALSE;
  416.     if (!Scr->HaveFonts) CreateFonts();
  417. #ifdef DEBUG
  418.     printf("after CreateFonts\n");
  419. #endif
  420.     CreateGCs();
  421. #ifdef DEBUG
  422.     printf("after CreateGCs\n");
  423. #endif
  424.     MakeMenus();
  425.  
  426. #ifdef DEBUG
  427.     printf("after MakeMenus\n");
  428. #endif
  429.     Scr->TitleBarFont.y += Scr->FramePadding;
  430.     Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2;
  431.     /* make title height be odd so buttons look nice and centered */
  432.     if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
  433.  
  434.     InitTitlebarButtons ();        /* menus are now loaded! */
  435.  
  436.     XGrabServer(dpy);
  437.     XSync(dpy, 0);
  438.  
  439. #ifdef DEBUG
  440.     printf("after XGrabServer & XSync\n");
  441. #endif
  442.  
  443.     JunkX = 0;
  444.     JunkY = 0;
  445.  
  446.     XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren);
  447.     CreateIconManagers();
  448.     if (!Scr->NoIconManagers)
  449.         Scr->iconmgr.twm_win->icon = TRUE;
  450.  
  451.     /*
  452.      * weed out icon windows
  453.      */
  454.     for (i = 0; i < nchildren; i++) {
  455.         if (children[i]) {
  456.         XWMHints *wmhintsp = XGetWMHints (dpy, children[i]);
  457.  
  458.         if (wmhintsp) {
  459.             if (wmhintsp->flags & IconWindowHint) {
  460.             for (j = 0; j < nchildren; j++) {
  461.                 if (children[j] == wmhintsp->icon_window) {
  462.                 children[j] = None;
  463.                 break;
  464.                 }
  465.             }
  466.             }
  467.             XFree ((char *) wmhintsp);
  468.         }
  469.         }
  470.     }
  471.  
  472.     /*
  473.      * map all of the non-override windows
  474.      */
  475.     for (i = 0; i < nchildren; i++)
  476.     {
  477.         if (children[i] && MappedNotOverride(children[i]))
  478.         {
  479.         XUnmapWindow(dpy, children[i]);
  480.         SimulateMapRequest(children[i]);
  481.         }
  482.     }
  483.  
  484.     if (Scr->ShowIconManager && !Scr->NoIconManagers)
  485.     {
  486.         Scr->iconmgr.twm_win->icon = FALSE;
  487.         if (Scr->iconmgr.count)
  488.         {
  489.         SetMapStateProp (Scr->iconmgr.twm_win, NormalState);
  490.         XMapWindow(dpy, Scr->iconmgr.w);
  491.         XMapWindow(dpy, Scr->iconmgr.twm_win->frame);
  492.         }
  493.     }
  494.  
  495. #ifdef DEBUG
  496.     printf("after mapping icon manager\n");
  497. #endif
  498.     
  499.     attributes.border_pixel = Scr->DefaultC.fore;
  500.     attributes.background_pixel = Scr->DefaultC.back;
  501.     attributes.event_mask = (ExposureMask | ButtonPressMask |
  502.                  KeyPressMask | ButtonReleaseMask);
  503.     attributes.backing_store = NotUseful;
  504.     attributes.cursor = XCreateFontCursor (dpy, XC_hand2);
  505.     valuemask = (CWBorderPixel | CWBackPixel | CWEventMask | 
  506.              CWBackingStore | CWCursor);
  507.     Scr->InfoWindow = XCreateWindow (dpy, Scr->Root, 0, 0, 
  508.                      (unsigned int) 5, (unsigned int) 5,
  509.                      (unsigned int) BW, 0,
  510.                      (unsigned int) CopyFromParent,
  511.                      (Visual *) CopyFromParent,
  512.                      valuemask, &attributes);
  513.  
  514.     Scr->SizeStringWidth = XTextWidth (Scr->SizeFont.font,
  515.                        " 8888 x 8888 ", 13);
  516.     valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity);
  517.     attributes.bit_gravity = NorthWestGravity;
  518.     Scr->SizeWindow = XCreateWindow (dpy, Scr->Root, 0, 0, 
  519.                      (unsigned int) Scr->SizeStringWidth,
  520.                      (unsigned int) (Scr->SizeFont.height +
  521.                              SIZE_VINDENT*2),
  522.                      (unsigned int) BW, 0,
  523.                      (unsigned int) CopyFromParent,
  524.                      (Visual *) CopyFromParent,
  525.                      valuemask, &attributes);
  526.  
  527.     XUngrabServer(dpy);
  528.  
  529. #ifdef DEBUG
  530.     printf("after creating windows and XUnGrabbing server\n");
  531. #endif
  532.     FirstScreen = FALSE;
  533.         Scr->FirstTime = FALSE;
  534.     } /* for */
  535.  
  536.     if (numManaged == 0) {
  537.     if (MultiScreen && NumScreens > 0)
  538.       fprintf (stderr, "%s:  unable to find any unmanaged screens\n",
  539.            ProgramName);
  540.     exit (1);
  541.     }
  542.  
  543.     RestartPreviousState = False;
  544.     HandlingEvents = TRUE;
  545.     InitEvents();
  546.     HandleEvents();
  547. }
  548.  
  549. /***********************************************************************
  550.  *
  551.  *  Procedure:
  552.  *    InitVariables - initialize twm variables
  553.  *
  554.  ***********************************************************************
  555.  */
  556.  
  557. InitVariables()
  558. {
  559.     FreeList(&Scr->BorderColorL);
  560.     FreeList(&Scr->IconBorderColorL);
  561.     FreeList(&Scr->BorderTileForegroundL);
  562.     FreeList(&Scr->BorderTileBackgroundL);
  563.     FreeList(&Scr->TitleForegroundL);
  564.     FreeList(&Scr->TitleBackgroundL);
  565.     FreeList(&Scr->IconForegroundL);
  566.     FreeList(&Scr->IconBackgroundL);
  567.     FreeList(&Scr->IconManagerFL);
  568.     FreeList(&Scr->IconManagerBL);
  569.     FreeList(&Scr->IconMgrs);
  570.     FreeList(&Scr->NoTitle);
  571.     FreeList(&Scr->MakeTitle);
  572.     FreeList(&Scr->AutoRaise);
  573.     FreeList(&Scr->IconNames);
  574.     FreeList(&Scr->NoHighlight);
  575.     FreeList(&Scr->NoStackModeL);
  576.     FreeList(&Scr->NoTitleHighlight);
  577.     FreeList(&Scr->DontIconify);
  578.     FreeList(&Scr->IconMgrNoShow);
  579.     FreeList(&Scr->IconMgrShow);
  580.     FreeList(&Scr->IconifyByUn);
  581.     FreeList(&Scr->StartIconified);
  582.     FreeList(&Scr->IconManagerHighlightL);
  583.     FreeList(&Scr->SqueezeTitleL);
  584.     FreeList(&Scr->DontSqueezeTitleL);
  585.     FreeList(&Scr->WindowRingL);
  586.     FreeList(&Scr->WarpCursorL);
  587.  
  588.     NewFontCursor(&Scr->FrameCursor, "top_left_arrow");
  589.     NewFontCursor(&Scr->TitleCursor, "top_left_arrow");
  590.     NewFontCursor(&Scr->IconCursor, "top_left_arrow");
  591.     NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow");
  592.     NewFontCursor(&Scr->MoveCursor, "fleur");
  593.     NewFontCursor(&Scr->ResizeCursor, "fleur");
  594.     NewFontCursor(&Scr->MenuCursor, "sb_left_arrow");
  595.     NewFontCursor(&Scr->ButtonCursor, "hand2");
  596.     NewFontCursor(&Scr->WaitCursor, "watch");
  597.     NewFontCursor(&Scr->SelectCursor, "dot");
  598.     NewFontCursor(&Scr->DestroyCursor, "pirate");
  599.  
  600.     Scr->Ring = NULL;
  601.     Scr->RingLeader = NULL;
  602.  
  603.     Scr->DefaultC.fore = black;
  604.     Scr->DefaultC.back = white;
  605.     Scr->BorderColor = black;
  606.     Scr->BorderTileC.fore = black;
  607.     Scr->BorderTileC.back = white;
  608.     Scr->TitleC.fore = black;
  609.     Scr->TitleC.back = white;
  610.     Scr->MenuC.fore = black;
  611.     Scr->MenuC.back = white;
  612.     Scr->MenuTitleC.fore = black;
  613.     Scr->MenuTitleC.back = white;
  614.     Scr->MenuShadowColor = black;
  615.     Scr->IconC.fore = black;
  616.     Scr->IconC.back = white;
  617.     Scr->IconBorderColor = black;
  618.     Scr->IconManagerC.fore = black;
  619.     Scr->IconManagerC.back = white;
  620.     Scr->IconManagerHighlight = black;
  621.  
  622.     Scr->FramePadding = 2;        /* values that look "nice" on */
  623.     Scr->TitlePadding = 8;        /* 75 and 100dpi displays */
  624.     Scr->ButtonIndent = 1;
  625.     Scr->SizeStringOffset = 0;
  626.     Scr->BorderWidth = BW;
  627.     Scr->IconBorderWidth = BW;
  628.     Scr->UnknownWidth = 0;
  629.     Scr->UnknownHeight = 0;
  630.     Scr->NumAutoRaises = 0;
  631.     Scr->NoDefaults = FALSE;
  632.     Scr->UsePPosition = PPOS_OFF;
  633.     Scr->FocusRoot = TRUE;
  634.     Scr->Focus = NULL;
  635.     Scr->WarpCursor = FALSE;
  636.     Scr->ForceIcon = FALSE;
  637.     Scr->NoGrabServer = FALSE;
  638.     Scr->NoRaiseMove = FALSE;
  639.     Scr->NoRaiseResize = FALSE;
  640.     Scr->NoRaiseDeicon = FALSE;
  641.     Scr->NoRaiseWarp = FALSE;
  642.     Scr->DontMoveOff = FALSE;
  643.     Scr->DoZoom = FALSE;
  644.     Scr->TitleFocus = TRUE;
  645.     Scr->NoTitlebar = FALSE;
  646.     Scr->DecorateTransients = FALSE;
  647.     Scr->IconifyByUnmapping = FALSE;
  648.     Scr->ShowIconManager = FALSE;
  649.     Scr->IconManagerDontShow =FALSE;
  650.     Scr->BackingStore = TRUE;
  651.     Scr->SaveUnder = TRUE;
  652.     Scr->RandomPlacement = FALSE;
  653.     Scr->OpaqueMove = FALSE;
  654.     Scr->Highlight = TRUE;
  655.     Scr->StackMode = TRUE;
  656.     Scr->TitleHighlight = TRUE;
  657.     Scr->MoveDelta = 1;        /* so that f.deltastop will work */
  658.     Scr->ZoomCount = 8;
  659.     Scr->SortIconMgr = FALSE;
  660.     Scr->Shadow = TRUE;
  661.     Scr->InterpolateMenuColors = FALSE;
  662.     Scr->NoIconManagers = FALSE;
  663.     Scr->ClientBorderWidth = FALSE;
  664.     Scr->SqueezeTitle = -1;
  665.     Scr->FirstRegion = NULL;
  666.     Scr->LastRegion = NULL;
  667.     Scr->FirstTime = TRUE;
  668.     Scr->HaveFonts = FALSE;        /* i.e. not loaded yet */
  669.     Scr->CaseSensitive = TRUE;
  670.     Scr->WarpUnmapped = FALSE;
  671.  
  672.     /* setup default fonts; overridden by defaults from system.twmrc */
  673. #define DEFAULT_NICE_FONT "variable"
  674. #define DEFAULT_FAST_FONT "fixed"
  675.  
  676.     Scr->TitleBarFont.font = NULL;
  677.     Scr->TitleBarFont.name = DEFAULT_NICE_FONT;
  678.     Scr->MenuFont.font = NULL;
  679.     Scr->MenuFont.name = DEFAULT_NICE_FONT;
  680.     Scr->IconFont.font = NULL;
  681.     Scr->IconFont.name = DEFAULT_NICE_FONT;
  682.     Scr->SizeFont.font = NULL;
  683.     Scr->SizeFont.name = DEFAULT_FAST_FONT;
  684.     Scr->IconManagerFont.font = NULL;
  685.     Scr->IconManagerFont.name = DEFAULT_NICE_FONT;
  686.     Scr->DefaultFont.font = NULL;
  687.     Scr->DefaultFont.name = DEFAULT_FAST_FONT;
  688.  
  689. }
  690.  
  691.  
  692. CreateFonts ()
  693. {
  694.     GetFont(&Scr->TitleBarFont);
  695.     GetFont(&Scr->MenuFont);
  696.     GetFont(&Scr->IconFont);
  697.     GetFont(&Scr->SizeFont);
  698.     GetFont(&Scr->IconManagerFont);
  699.     GetFont(&Scr->DefaultFont);
  700.     Scr->HaveFonts = TRUE;
  701. }
  702.  
  703.  
  704. RestoreWithdrawnLocation (tmp)
  705.     TwmWindow *tmp;
  706. {
  707.     int gravx, gravy;
  708.     unsigned int bw, mask;
  709.     XWindowChanges xwc;
  710.  
  711.     if (XGetGeometry (dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y, 
  712.               &JunkWidth, &JunkHeight, &bw, &JunkDepth)) {
  713.  
  714.     GetGravityOffsets (tmp, &gravx, &gravy);
  715.     if (gravy < 0) xwc.y -= tmp->title_height;
  716.  
  717.     if (bw != tmp->old_bw) {
  718.         int xoff, yoff;
  719.  
  720.         if (!Scr->ClientBorderWidth) {
  721.         xoff = gravx;
  722.         yoff = gravy;
  723.         } else {
  724.         xoff = 0;
  725.         yoff = 0;
  726.         }
  727.  
  728.         xwc.x -= (xoff + 1) * tmp->old_bw;
  729.         xwc.y -= (yoff + 1) * tmp->old_bw;
  730.     }
  731.     if (!Scr->ClientBorderWidth) {
  732.         xwc.x += gravx * tmp->frame_bw;
  733.         xwc.y += gravy * tmp->frame_bw;
  734.     }
  735.  
  736.     mask = (CWX | CWY);
  737.     if (bw != tmp->old_bw) {
  738.         xwc.border_width = tmp->old_bw;
  739.         mask |= CWBorderWidth;
  740.     }
  741.  
  742.     XConfigureWindow (dpy, tmp->w, mask, &xwc);
  743.  
  744.     if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) {
  745.         XUnmapWindow (dpy, tmp->wmhints->icon_window);
  746.     }
  747.  
  748.     }
  749. }
  750.  
  751.  
  752. /***********************************************************************
  753.  *
  754.  *  Procedure:
  755.  *    Done - cleanup and exit twm
  756.  *
  757.  *  Returned Value:
  758.  *    none
  759.  *
  760.  *  Inputs:
  761.  *    none
  762.  *
  763.  *  Outputs:
  764.  *    none
  765.  *
  766.  *  Special Considerations:
  767.  *    none
  768.  *
  769.  ***********************************************************************
  770.  */
  771.  
  772. void Reborder (time)
  773. Time time;
  774. {
  775.     TwmWindow *tmp;            /* temp twm window structure */
  776.     int scrnum;
  777.  
  778.     /* put a border back around all windows */
  779.  
  780.     XGrabServer (dpy);
  781.     for (scrnum = 0; scrnum < NumScreens; scrnum++)
  782.     {
  783.     if ((Scr = ScreenList[scrnum]) == NULL)
  784.         continue;
  785.  
  786.     InstallWindowColormaps (0, &Scr->TwmRoot);    /* force reinstall */
  787.     for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next)
  788.     {
  789.         RestoreWithdrawnLocation (tmp);
  790.         XMapWindow (dpy, tmp->w);
  791.     }
  792.     }
  793.  
  794.     XUngrabServer (dpy);
  795.     SetFocus ((TwmWindow*)NULL, time);
  796. }
  797.  
  798. SIGNAL_T Done()
  799. {
  800.     Reborder (CurrentTime);
  801.     XCloseDisplay(dpy);
  802.     exit(0);
  803.     SIGNAL_RETURN;
  804. }
  805.  
  806.  
  807. /*
  808.  * Error Handlers.  If a client dies, we'll get a BadWindow error (except for
  809.  * GetGeometry which returns BadDrawable) for most operations that we do before
  810.  * manipulating the client's window.
  811.  */
  812.  
  813. Bool ErrorOccurred = False;
  814. XErrorEvent LastErrorEvent;
  815.  
  816. static int TwmErrorHandler(dpy, event)
  817.     Display *dpy;
  818.     XErrorEvent *event;
  819. {
  820.     LastErrorEvent = *event;
  821.     ErrorOccurred = True;
  822.  
  823.     if (PrintErrorMessages &&             /* don't be too obnoxious */
  824.     event->error_code != BadWindow &&    /* watch for dead puppies */
  825.     (event->request_code != X_GetGeometry &&     /* of all styles */
  826.      event->error_code != BadDrawable))
  827.       XmuPrintDefaultErrorMessage (dpy, event, stderr);
  828.     return 0;
  829. }
  830.  
  831.  
  832. /* ARGSUSED*/
  833. static int CatchRedirectError(dpy, event)
  834.     Display *dpy;
  835.     XErrorEvent *event;
  836. {
  837.     RedirectError = TRUE;
  838.     LastErrorEvent = *event;
  839.     ErrorOccurred = True;
  840.     return 0;
  841. }
  842.  
  843. Atom _XA_MIT_PRIORITY_COLORS;
  844. Atom _XA_WM_CHANGE_STATE;
  845. Atom _XA_WM_STATE;
  846. Atom _XA_WM_COLORMAP_WINDOWS;
  847. Atom _XA_WM_PROTOCOLS;
  848. Atom _XA_WM_TAKE_FOCUS;
  849. Atom _XA_WM_SAVE_YOURSELF;
  850. Atom _XA_WM_DELETE_WINDOW;
  851.  
  852. InternUsefulAtoms ()
  853. {
  854.     /* 
  855.      * Create priority colors if necessary.
  856.      */
  857.     _XA_MIT_PRIORITY_COLORS = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", False);   
  858.     _XA_WM_CHANGE_STATE = XInternAtom (dpy, "WM_CHANGE_STATE", False);
  859.     _XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False);
  860.     _XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False);
  861.     _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
  862.     _XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False);
  863.     _XA_WM_SAVE_YOURSELF = XInternAtom (dpy, "WM_SAVE_YOURSELF", False);
  864.     _XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
  865. }
  866.